#include "xInMappingPort.h"
#include "xParameterPack.h"
#include "xOutMappingPort.h"
#include "xNodeType.h"
#include "xMappingNode.h"

template <class T>
bool from_string(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&))
{
	std::istringstream iss(s);
	return !(iss >> f >> t).fail();
}

xParameter xInMappingPort::toXParameter() { 
	xParameter xp ;
	if (_link != NULL) {
		xOutMappingPort *outp = _link->left ;
		xNodeType *np = outp->getParent()->getNodeTypePtr();
		xp = np->toXParameter(_type, outp);
		return xp ;
	} else {  // this port has no link to other port, use default value to create a xParameter
		// the default value is stored in the VM.des file. 
		// the last field of a para
		xp.type = _type ;
		if (_type =="int") 	{
			int value ;
			if(from_string<int>(value, std::string(_defaultvalue), std::boolalpha)) xp.val_int = value ;
			else assert(false);
		} else if (_type == "bool") {
			bool value ;
			if(from_string<bool>(value, std::string(_defaultvalue), std::boolalpha)) xp.val_bool = value ;
			else assert(false);
		} else if (_type == "int*") {
			int *value = new int ;
			if (_defaultvalue == "NULL"){
				xp.val_int_ptr = NULL;
				delete value;
			}
			else if (from_string<int>(*value, std::string(_defaultvalue), std::boolalpha)){
				xp.val_int_ptr = value ;
			}
			else{
				assert(false);
				delete value;				
			}			
		} else if (_type == "string") {
			if (_defaultvalue == "NULL") xp.val_string = "";
			else xp.val_string = _defaultvalue;
		} else if (_type == "tostring*") {
			if (_defaultvalue == "NULL")xp.val_string_ptr = NULL;
			else assert(false);
		} else if (_type == "Quaternion*") {
			if (_defaultvalue == "NULL")xp.val_quaternion_ptr = NULL;
			else assert(false);
		} else if (_type == "wop") {
			if (_defaultvalue == "NULL") xp.val_wop = NULL;
			else assert(false);
		} else if (_type == "varname") {
			if (_defaultvalue == "NULL") xp.val_string = "" ; 
			else xp.val_string = _defaultvalue;
		} else if (_type == "double") {
			double value ;
			if(from_string<double>(value, std::string(_defaultvalue), std::boolalpha)) xp.val_double = value ;
			else assert(false);			
		} else if (_type == "double*") {
			double *value = new double ;
			if (_defaultvalue == "NULL"){
				xp.val_double_ptr= NULL ;
				delete value;
			}
			else if(from_string<double>(*value, std::string(_defaultvalue), std::boolalpha)){
				xp.val_double_ptr = value;
			}
			else{
				assert(false);
				delete value;
			}
		}  else if (_type == "float") {
			float value ;
			if(from_string<float>(value, std::string(_defaultvalue), std::boolalpha)) xp.val_float = value ;
			else assert(false);			

		} else if (_type == "float*") {
			float *value = new float ;
			if (_defaultvalue == "NULL"){
				xp.val_float_ptr=NULL ;
				delete value;
			}
			else if(from_string<float>(*value, std::string(_defaultvalue), std::boolalpha)){
				xp.val_float_ptr = value;
			}
			else{
				assert(false);
				delete value;
			}			
		} else if (_type == "Degree*") {

		}
		else
			assert(false);
		return xp ;
	}

}
int xInMappingPort::getIndexOfParent() {
	for (int i = 0; i< _node_parent->getInportSize(); i++) {
		if (this == _node_parent->getInPort(i))
			return i ;
	}
	assert(false);
	return -1 ;
}

